package service

import (
	"context"
	"errors"
	"github.com/duke-git/lancet/v2/retry"
	"shorten/internal/dao"
	"shorten/internal/model"
	"time"
)

type ShortenGenParam struct {
	Url string `json:"url" binding:"required,min=3,max=100,url"`
}

func (s *Service) GetUrlBySign(ctx context.Context, sign string) (string, error) {
	//1 先从缓存中获取短地址
	urlCache := dao.CommonHashGet(ctx, dao.URL_KEY, sign)
	//2 缓存中有则直接返回
	if urlCache != "" {
		return urlCache, nil
	}
	//3 没有则查找数据库
	url := dao.GetOneUrl(sign)
	//4 数据库中没有则返回错误
	if url == "" {
		return "", errors.New("url not found")
	}
	//5 有则写入缓存
	err := dao.CommonHashSet(ctx, dao.URL_KEY, sign, url)
	return url, err
}

func (s *Service) GenSign(userId int, url string) (string, error) {
	//1 判断当前url有没有记录
	exist := dao.GetOneShorten(map[string]any{"base_url": url}, []string{"*"})
	if exist.ShortSign != "" {
		return exist.ShortSign, nil
	}
	//2 若是新地址则重新生成
	sign := ""
	err := retry.Retry(func() error {
		//sign = random.RandNumeralOrLetter(9)
		sign = "Vw4NboWUN"
		data := &model.Shorten{
			UserId:    userId,
			BaseUrl:   url,
			ShortSign: sign,
		}
		return dao.DB().Create(&data).Error
	}, retry.RetryTimes(3), retry.RetryWithCustomBackoff(RetryTimeOut{}))
	return sign, err
}

type RetryTimeOut struct {
}

func (r RetryTimeOut) CalculateInterval() time.Duration {
	return time.Second * 1
}
